#include "ggear_window.h"

namespace ggear
{
	namespace sys
	{
		Window::Window(u32 _width, u32 _height)
		{
			RECT wndRect;

			DWORD dwStyle = WS_OVERLAPPED | WS_VISIBLE;

			WNDCLASS wcls;
			wcls.hInstance = GetModuleHandle(null);
			wcls.lpszClassName = TEXT("GGear");
			wcls.lpfnWndProc = Window::windowProcess;
			wcls.style = CS_VREDRAW | CS_HREDRAW | CS_OWNDC;
			wcls.hCursor = LoadCursor(null, IDC_ARROW);
			wcls.hIcon = LoadIcon(null, IDI_APPLICATION);
			wcls.lpszMenuName = null;
			wcls.hbrBackground = null;
			wcls.cbClsExtra = null;
			wcls.cbWndExtra = null;

			if(!RegisterClass(&wcls)) throw "Exception";

			if(!_width) _width = CW_USEDEFAULT;	
			if(!_height) _height = CW_USEDEFAULT;

			mSize.Width = _width;
			mSize.Height = _height;
			mPosition.X = mPosition.Y = CW_USEDEFAULT;
			wndRect = mSize;

			AdjustWindowRect(&wndRect, dwStyle, false);
			
			mHWnd = CreateWindow(TEXT("GGear"), TEXT("GGear"),dwStyle,
				mPosition.X, mPosition.Y,
				wndRect.right - wndRect.left, wndRect.bottom - wndRect.top,
				null, null, GetModuleHandle(null), null);

			if(!mHWnd) throw "Exception";

			mHDC = GetDC(mHWnd);
		}

		Window::~Window()
		{
			//Do nothing
		}

		HDC Window::hdc() const
		{
			return mHDC;
		}

		u32 Window::left() const
		{
			return mPosition.X;
		}

		u32 Window::top() const
		{
			return mPosition.Y;
		}

		u32 Window::width() const
		{
			return mSize.Width;
		}

		u32 Window::height() const
		{
			return mSize.Height;
		}

		glb::String Window::title() const
		{
			return mTitle;
		}

		void Window::show() const
		{
			UpdateWindow(mHWnd);
			ShowWindow(mHWnd, SW_SHOW);

			MSG msg;
			bool quitting = false;
			while(!quitting)
			{
				while(PeekMessage(&msg, null, null, null, PM_REMOVE))
				{
					if(msg.message == WM_QUIT)
					{
						quitting = true;
						break;
					}
					else
					{
						TranslateMessage(&msg);
						DispatchMessage(&msg);
					}
				}
			}
		}

		LRESULT CALLBACK Window::windowProcess(HWND _hwnd, UINT _msg, WPARAM _wp, LPARAM _lp)
		{
			switch(_msg)
			{
			case WM_CLOSE:
				PostQuitMessage(0);
				break;

			default:
				return DefWindowProc(_hwnd, _msg, _wp, _lp);
			}
			return 0;
		}
	}
}